﻿using Gl_mes.BLL.Mes;
using Gl_mes.DAL.MesDB;
using MesGLApp.BLL;
using MesGLApp.BLL.Mes;
using MesGLApp.DAL.MesDB;
using MesGLApp.DAL.MesDTO;
using MesGLApp.DAL.RoleDB;
using MesGLApp.DAL.RoleDTO;
using MesGLApp.View.Search;
using Smobiler.Core;
using Smobiler.Core.Controls;
using SqlSugar;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection.Emit;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ToolBar;
using TextBox = Smobiler.Core.Controls.TextBox;

namespace MesGLApp.View.Scan
{
    partial class OtherSiteScanFrm : Smobiler.Core.Controls.MobileForm
    {

        DataTable PCBSMTDetail = new DataTable();

        //private KingdeeControler _king_ctrl = new KingdeeControler();
        BaseControler bs = new BaseControler();
        private SqlSugarClient Db = SqlSugares.GetInstance();
        int SYG_SiteID = 0;//上一站id
        string SYGPCB = "";//上一个PCB型号
        public OtherSiteScanFrm() : base()
        {
            //This call is required by the SmobilerForm.
            InitializeComponent();
        }

        #region "内部变量"
        private ProdProcScanControler _ctrl = new ProdProcScanControler();
        private SiteControler _site_ctrl = new SiteControler();
        private List<SiteInfo> _site_list = new List<SiteInfo>();
        private List<StatusInfo> _status_list = new List<StatusInfo>();
        private List<UserSite> _user_site_list = new List<UserSite>();
        private SiteInfo _curr_site = null;
        private StatusInfo _curr_status = null;
        #endregion


        #region "控件事件"
        /// <summary>
        /// 界面读入时加载所有站点信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OtherSiteScanFrm_Load(object sender, EventArgs e)
        {
            //界面Loading时，读取所有状态和子站点信息
            this._status_list = this._ctrl.SearchAllStatus();
            this._site_list = this._ctrl.SearchAllSiteInfo();
            this.InitSitePopList();
        }

        /// <summary>
        /// 打开站点选择框
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSite_Press(object sender, EventArgs e)
        {
            if (this.popSite.Groups.Count <= 0 || this.popSite.Groups[0].Items == null || this.popSite.Groups[0].Items.Count <= 0)
            {
                MessageBox.Show("当前用户尚未分配站点！", "异常");
            }
            else
            {
                this.popSite.ShowDialog();
            }

        }

        /// <summary>
        /// 选择站点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void popSite_Selected(object sender, EventArgs e)
        {
            this.btnSite.Text = popSite.Selection.Text.Trim();
            if (this._site_list != null && this._site_list.Count > 0 && this._status_list != null && this._status_list.Count > 0)
            {
                var siteQuery = this._site_list.Where(s => s.SiteName == popSite.Selection.Text.Trim());
                if (siteQuery != null && siteQuery.Count() > 0)
                {
                    this._curr_site = siteQuery.First<SiteInfo>();
                    var statusQuery = this._status_list.Where(s => s.ID == (this._curr_site.DefStatus ?? 0));
                    if (statusQuery != null && statusQuery.Count() > 0)
                    {
                        this._curr_status = statusQuery.First<StatusInfo>();
                        this.lblStatus.Text = this._curr_status.StatusValue.ToString().Trim();
                    }
                }
            }

            this.label2.Text = "";
            this.label4.Text = "";
            this.label6.Text = "";
            this.textBox1.Text = "";
            this.txtProdNumber.Text = "";
        }

        /// <summary>
        /// 扫描工单号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnScan_BarcodeScanned(object sender, BarcodeResultArgs e)
        {
            if (e.Value != null && e.Value.ToString().Length > 0)
            {
                this.txtProdNumber.Text = e.Value.ToString();
            }

            this.SearchTargetInfo();
        }

        /// <summary>
        /// 手工输入工单号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtProdNumber_SubmitEditing(object sender, EventArgs e)
        {
            if (this.txtProdNumber.Text.Trim().Equals("") == false)
            {
                this.SearchTargetInfo();
            }
        }
        #endregion

        #region "内部方法"
        /// <summary>
        /// 查询工单信息
        /// </summary>
        private void SearchTargetInfo()
        {
            //查询工单相关信息，并检查信息是否有误，如果有异常，将异常提示用户，并中止扫码。
            TargetProdProcessDTO tmpTarget = this._ctrl.SearchTargetForScan(this.txtProdNumber.Text.Trim());
            if (tmpTarget == null)
            {
                MessageBox.Show("工单号不存在！");
                this.txtProdNumber.Text = "";
                return;
            }
            if (this._curr_site == null)
            {
                MessageBox.Show("请先选择站点！");
                this.txtProdNumber.Text = "";
                return;
            }
            else
            {
                SiteScanDTO tmpEntry = this.InitSiteScanDTO(tmpTarget,this._curr_site);
                if (tmpEntry is null)
                {
                    MessageBox.Show("无法确定工单的扫码信息，中止扫码！", "错误");
                    this.btnSave.Enabled = false;
                }
                else
                {
                    this.label2.Text = Math.Round((tmpTarget.ProdQty ?? 0), 3).ToString();
                    this.label4.Text = Math.Round(tmpEntry.clear_qty, 3).ToString();
                    this.label6.Text = Math.Round(tmpEntry.last_qty, 3).ToString();
                    this.textBox1.Text = Math.Round(tmpEntry.surp_qty, 3).ToString();
                }

                if ((SYG_SiteID == 6 || SYG_SiteID == 7 || SYG_SiteID == 8) && (this._curr_site.ID != 6 && this._curr_site.ID != 7 && this._curr_site.ID != 8))
                {
                    //查找上一站，也就是炉后站已扫描数量
                    decimal sumQty = Db.Context.Queryable<SmtPcbScan>().Where(d => d.site_id == SYG_SiteID && d.prod_number == tmpTarget.ProdNumber).ToList()
                                                                            .Sum(d => d.pcb_scan_qty).ObjToDecimal();
                    //查看PCB总数量
                    decimal sunConfirmQty = Db.Context.Queryable<SmtPcbConfirm>().Where(d => d.prod_number == tmpTarget.ProdNumber).ToList().Sum(d => d.confirm_qty).ObjToDecimal();
                    if (sumQty != sunConfirmQty)
                    {
                        MessageBox.Show("SMT站还没扫完PCB数量，不能转料！");
                        this.txtProdNumber.Text = "";
                        return;
                    }
                    else
                    {
                        label6.Text = tmpTarget.ProdQty.ToString();//上一站数量
                        label2.Text = tmpTarget.ProdQty.ToString();//工单数量
                    }
                }
                //贴片炉后进入这里
                if (this._curr_site.ID == 6 || this._curr_site.ID == 7 || this._curr_site.ID == 8)
                {
                    //显示控件
                    label9.Visible = true;
                    label10.Visible = true;
                    label11.Visible = true;
                    SYGNumber.Visible = true;
                    YFPNumber.Visible = true;
                    OKNumber.Visible = true;
                    label8.Visible = true;
                    comboBox1.Visible = true;
                    ItemDetailAsync(tmpTarget);
                    textBox1.Text = "";
                    textBox1.Visible = false;
                }
                else
                {
                    //显示控件
                    label9.Visible = false;
                    label10.Visible = false;
                    label11.Visible = false;
                    SYGNumber.Visible = false;
                    YFPNumber.Visible = false;
                    OKNumber.Visible = false;
                    label8.Visible = false;
                    comboBox1.Visible = false;
                    textBox1.Visible = true;
                }
            }
        }
        /// <summary>
        /// SMT站点PCB型号数量
        /// </summary>
        /// <param name="tmpTarget"></param>
        private async Task ItemDetailAsync(TargetProdProcessDTO tmpTarget)
        {
            PCBSMTDetail = new DataTable();
            PCBSMTDetail.Columns.Add("ItemCode", typeof(string));//型号
            PCBSMTDetail.Columns.Add("SYGNumber", typeof(string));//上一站扫码数量
            PCBSMTDetail.Columns.Add("YFPNumber", typeof(string));//已分配数量
            PCBSMTDetail.Columns.Add("OKNumber", typeof(string));//确认数量 
            comboBox1.Items.Clear();
            decimal SYGpcb_scan_qtySum = 0;//上一站某型号数量
            decimal SYGSUM = 0;//上一站总数量
            List<SmtPcbConfirm> pcbConfirm = Db.Context.Queryable<SmtPcbConfirm>().Where(d => d.prod_number == tmpTarget.ProdNumber).ToList();
            for (int i = 0; i < pcbConfirm.Count; i++)
            {
                //查询到已分配数量
                if (this._curr_site.ID == 7)
                {
                    SYGpcb_scan_qtySum = Db.Context.Queryable<SmtPcbScan>().Where(d => d.site_id == 6 && d.prod_number == tmpTarget.ProdNumber && d.mat_number == pcbConfirm[i].mat_number).ToList().Sum(d => d.pcb_scan_qty).ObjToDecimal();
                    SYGSUM = Db.Context.Queryable<SmtPcbScan>().Where(d => d.site_id == 6 && d.prod_number == tmpTarget.ProdNumber).ToList().Sum(d => d.pcb_scan_qty).ObjToDecimal();
                }
                if (this._curr_site.ID == 8)
                {
                    SYGpcb_scan_qtySum = Db.Context.Queryable<SmtPcbScan>().Where(d => d.site_id == 7 && d.prod_number == tmpTarget.ProdNumber && d.mat_number == pcbConfirm[i].mat_number).ToList().Sum(d => d.pcb_scan_qty).ObjToDecimal();
                    SYGSUM = Db.Context.Queryable<SmtPcbScan>().Where(d => d.site_id == 7 && d.prod_number == tmpTarget.ProdNumber).ToList().Sum(d => d.pcb_scan_qty).ObjToDecimal();
                }
                decimal Thispcb_scan_qtySum = Db.Context.Queryable<SmtPcbScan>().Where(d => d.site_id == this._curr_site.ID && d.prod_number == tmpTarget.ProdNumber && d.mat_number == pcbConfirm[i].mat_number).ToList().Sum(d => d.pcb_scan_qty).ObjToDecimal();
                PCBSMTDetail.Rows.Add(pcbConfirm[i].mat_number, SYGpcb_scan_qtySum, Thispcb_scan_qtySum, SYGpcb_scan_qtySum - Thispcb_scan_qtySum);
                comboBox1.Items.Add(pcbConfirm[i].mat_number);
            }
            label6.Text = SYGSUM.ToString();
            SYGNumber.Text = "";
            YFPNumber.Text = "";
            OKNumber.Text = "";
            SYGPCB = "";
            this.comboBox1.Text = "请选择PCB型号";
        }

        /// <summary>
        /// 查询所有站点，并将站点绑定到popList中
        /// </summary>
        private void InitSitePopList()
        {
            //先将站点列表中的站点清空
            this.popSite.Groups.Clear();

            if (this._site_list != null && this._site_list.Count > 0)
            {
                //分别取得当前登陆用户的权限信息，也通过登陆用户查询该用户可控制的站点
                List<int> deptIds = bs.SelectUserDept();
                List<UserSite> userSiteList = new List<UserSite>();
                if (Session.ContainsKey("User") && Client.Session["User"] != null)
                {
                    userSiteList = this._site_ctrl.SearchSiteInfoForUserID((Session["User"] as BaseUserDTO).id);
                }

                //先排除第6站点，即首件站，首件丫不能用该加拿大面
                var query = this._site_list.Where(q => q.ID != 6).OrderBy(q => q.SiteCode);
                if (query != null && query.Count() > 0)
                {
                    PopListGroup groups = new PopListGroup();
                    foreach (var item in query)
                    {
                        if (deptIds != null && deptIds.Count > 0 && deptIds.Contains(item.deptId))
                        {
                            if (userSiteList != null && userSiteList.Count > 0 && userSiteList.Select(q => q.SiteID).Contains(item.ID))
                            {
                                PopListItem popItem = new PopListItem(item.SiteName, item.ID.ToString());
                                groups.Items.Add(popItem);
                            }
                        }
                    }
                    this.popSite.Groups.Add(groups);
                }
            }
        }



        private SiteScanDTO InitSiteScanDTO(TargetProdProcessDTO prod, SiteInfo site)
        {
            SiteScanDTO resEntry = new SiteScanDTO();
            List<SiteInfo> parentList = this._ctrl.SearchAllParentSiteInfo();

            int tmpInt = 0;
            decimal tmpDec = 0;

            //取得当前扫码站点的相关信息
            var scanQuery = prod.SiteGroup.SiteInfoList.Join(parentList, s => s.SiteInfo.ParentID, p => p.ID, (s, p) => new { parent = p, child = s })
                                                            .Where(q => q.child.SiteID == site.ID);
            if (scanQuery != null && scanQuery.Count() > 0)
            {
                resEntry.scan_site = scanQuery.First().child;
                resEntry.scan_site.parent_site = scanQuery.First().parent;
            }

            //取得工单当前所在站点的相关信息
            var currQuery = prod.SiteGroup.SiteInfoList.Join(parentList, s => s.SiteInfo.ParentID, p => p.ID, (s, p) => new { parent = p, child = s })
                                                            .Where(q => q.child.SiteID == prod.CurrSiteID);
            if (currQuery != null && currQuery.Count() > 0)
            {
                resEntry.curr_site = currQuery.First().child;
                resEntry.curr_site.parent_site = currQuery.First().parent;
            }

            //取得工单制程的结束站点的相关信息
            var finallyQuery = prod.SiteGroup.SiteInfoList.Join(parentList, s => s.SiteInfo.ParentID, p => p.ID, (s, p) => new { parent = p, child = s })
                                                            .Where(q => q.child.IsLast == 1);
            if (finallyQuery != null && finallyQuery.Count() > 0)
            {
                resEntry.finally_site = finallyQuery.First().child;
                resEntry.finally_site.parent_site = finallyQuery.First().parent;
            }


            //如果当前扫码站点在工单制程之内，取得该站点的上一站点组
            if (string.IsNullOrEmpty(resEntry.scan_site.end_margin) == false)
            {
                //如果当前站点有列明上一站点的，取得上一站点的信息
                string[] splitSiteIDs = resEntry.scan_site.end_margin.Split(',');
                resEntry.last_site_list = new List<SiteInfoGroupDTO>();
                resEntry.is_first = false;
                foreach (var tmpSiteID in splitSiteIDs)
                {
                    if (int.TryParse(tmpSiteID, out tmpInt))
                    {
                        var lastQuery = prod.SiteGroup.SiteInfoList.Where(q => q.SiteID == tmpInt);
                        if (lastQuery != null && lastQuery.Count() > 0)
                        {
                            resEntry.last_site_list.Add(lastQuery.First<SiteInfoGroupDTO>());
                        }
                    }
                }
            }
            else if (resEntry.scan_site.is_margin.HasValue && ((int)resEntry.scan_site.is_margin) == 1)
            {
                //如果当前站点是并行流程，无上一站点，变量lastSiteList不为null，但没有子集
                resEntry.last_site_list = new List<SiteInfoGroupDTO>();
                resEntry.is_first = true;
            }
            else
            {
                //以上两种情况都不是的情况，按当前站点的排序（sort）来计算上一站点
                int tmpSort = resEntry.scan_site.Sort - 1;
                if (tmpSort <= 0)
                {
                    //如果计算出来的sort小于0，则当前站点为制程的首站，变量lastSiteList为null
                    resEntry.last_site_list = null;
                    resEntry.is_first = true;
                }
                else
                {
                    //如果计算出来的sort大于0，则按sort取得上一站点
                    var lastQuery = prod.SiteGroup.SiteInfoList.Where(q => q.Sort == tmpSort);
                    if (lastQuery != null && lastQuery.Count() > 0)
                    {
                        if (lastQuery.First().SiteID == 8)
                        {
                            resEntry.last_site_list = new List<SiteInfoGroupDTO>();
                            resEntry.is_first = true;
                        }
                        else
                        {
                            resEntry.last_site_list = new List<SiteInfoGroupDTO>();
                            resEntry.last_site_list.Add(lastQuery.First());
                            resEntry.is_first = false;
                        }
                    }
                }
            }

            //确定工单上一站的扫码数量
            if (resEntry.is_first)
            {
                //如果是首站，上一站扫码数量为工单的投产数量
                resEntry.last_qty = prod.ProdQty ?? 0;
            }
            else
            {
                //如果不是首站，查询所有上一站的扫码数量，取较小的为上一站扫码数量
                resEntry.last_qty = 0;
                if (resEntry.last_site_list != null && resEntry.last_site_list.Count > 0)
                {
                    foreach (var item in resEntry.last_site_list)
                    {
                        if (prod.scanList != null && prod.scanList.Count > 0)
                        {
                            var tmpQuery = prod.scanList.Where(q => q.SiteInfoID == item.SiteID);
                            tmpDec = tmpQuery != null && tmpQuery.Count() > 0 ? tmpQuery.Sum(q => q.ScanQty) : 0;
                        }
                        else
                        {
                            tmpDec = 0;
                        }
                        
                       
                        if (tmpDec > 0)
                        {
                            if (resEntry.last_qty == 0)
                            {
                                resEntry.last_qty = tmpDec;
                            }
                            else if (resEntry.last_qty != 0 && tmpDec < resEntry.last_qty)
                            {
                                resEntry.last_qty = tmpDec;
                            }
                        }
                    }
                }
            }

            tmpDec = 0;
            if (prod.scanList != null && prod.scanList.Count > 0)
            {
                var tmpQuery = prod.scanList.Where(q => q.SiteInfoID == resEntry.scan_site.SiteID);
                tmpDec = tmpQuery != null && tmpQuery.Count() > 0 ? tmpQuery.Sum(q => q.ScanQty) : 0;
            }
            resEntry.clear_qty = tmpDec;
            resEntry.surp_qty = resEntry.last_qty - resEntry.clear_qty;

            return resEntry;
        }


        /// <summary>
        /// 检查数据是否异常
        /// </summary>
        /// <param name="target"></param>
        /// <param name="user"></param>
        /// <param name="site"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        private (bool, string, SiteScanDTO) ChechData(TargetProdProcessDTO target, BaseUserModel user, SiteInfo site, StatusInfo status, decimal scanQty)
        {
            string errStr = "";
            bool isOK = true;
            SiteScanDTO resEntry = new SiteScanDTO();
            List<SiteInfo> parentList = this._ctrl.SearchAllParentSiteInfo();

            if (user == null || user.id <= 0)
            {
                isOK = false;
                errStr = "当前用户为空，中止扫码！";
                return (isOK, errStr, resEntry);
            }
            else if (site == null || site.ID <= 0)
            {
                isOK = false;
                errStr = "当前站点为空，中止扫码！";
                return (isOK, errStr, resEntry);
            }
            else if (status == null || status.ID <= 0)
            {
                isOK = false;
                errStr = "当前工单状态为空，中止扫码！";
                return (isOK, errStr, resEntry);
            }
            else if (status != null && (status.StatusValue.Equals("暂停") || status.StatusValue.Equals("取消暂停")))
            {
                isOK = false;
                errStr = "该界面不处理工单的暂停与取消暂停！";
                return (isOK, errStr, resEntry);
            }
            else if (target.SiteGroup == null || target.SiteGroup.SiteInfoList == null || target.SiteGroup.SiteInfoList.Count <= 0)
            {
                isOK = false;
                errStr = "工单号：" + target.ProdNumber + "没与站点组绑定，或其站点组没与站点绑定！";
                return (isOK, errStr, resEntry);
            }
            else
            {
                int tmpInt = 0;
                decimal tmpDec = 0;

                //取得当前扫码站点的相关信息
                var scanQuery = target.SiteGroup.SiteInfoList.Join(parentList, s => s.SiteInfo.ParentID, p => p.ID, (s, p) => new { parent = p, child = s })
                                                                .Where(q => q.child.SiteID == site.ID);
                if (scanQuery != null && scanQuery.Count() > 0)
                {
                    resEntry.scan_site = scanQuery.First().child;
                    resEntry.scan_site.parent_site = scanQuery.First().parent;
                }
                
                //取得工单当前所在站点的相关信息
                var currQuery = target.SiteGroup.SiteInfoList.Join(parentList, s => s.SiteInfo.ParentID, p => p.ID, (s, p) => new { parent = p, child = s })
                                                                .Where(q => q.child.SiteID == target.CurrSiteID);
                if (currQuery != null && currQuery.Count() > 0)
                {
                    resEntry.curr_site = currQuery.First().child;
                    resEntry.curr_site.parent_site = currQuery.First().parent;
                }

                //取得工单制程的结束站点的相关信息
                var finallyQuery = target.SiteGroup.SiteInfoList.Join(parentList, s => s.SiteInfo.ParentID, p => p.ID, (s, p) => new { parent = p, child = s })
                                                                .Where(q => q.child.IsLast == 1);
                if (finallyQuery != null && finallyQuery.Count() > 0)
                {
                    resEntry.finally_site = finallyQuery.First().child;
                    resEntry.finally_site.parent_site = finallyQuery.First().parent;
                }


                if (resEntry.scan_site is null || resEntry.scan_site.ID <= 0)
                {
                    //如果当前扫码站点不在工单的制程内，报异常
                    errStr = $@"该工单的流程不包括{site.SiteName}";
                    isOK = false;
                    return (isOK, errStr, resEntry);
                }
                else if (resEntry.scan_site.parent_site is null || resEntry.scan_site.parent_site.ID <= 0)
                {
                    //如果当前扫码站点没有父站点，报异常
                    errStr = $@"无法确定站点{site.SiteName}的父站点";
                    isOK = false;
                    return (isOK, errStr, resEntry);
                }
                else if (target.ErrStatusID == 21 && resEntry.scan_site.SiteID == resEntry.finally_site.SiteID)
                {
                    //如果工单为普通异常，不能扫最终站
                    errStr = $@"工单状态为普通异常，不能扫流程的最终站";
                    isOK = false;
                    return (isOK, errStr, resEntry);
                }
                else if (target.ErrStatusID == 7 && resEntry.scan_site.parent_site.ID != resEntry.curr_site.parent_site.ID)
                {
                    //如果工单为严重异常，不能过站
                    errStr = $@"工单状态为严重异常，不能过站";
                    isOK = false;
                    return (isOK, errStr, resEntry);
                }
                else
                {
                    //如果当前扫码站点在工单制程之内，取得该站点的上一站点组
                    if (string.IsNullOrEmpty(resEntry.scan_site.end_margin) == false)
                    {
                        //如果当前站点有列明上一站点的，取得上一站点的信息
                        string[] splitSiteIDs = resEntry.scan_site.end_margin.Split(',');
                        resEntry.last_site_list = new List<SiteInfoGroupDTO>();
                        resEntry.is_first = false;
                        foreach (var tmpSiteID in splitSiteIDs)
                        {
                            if (int.TryParse(tmpSiteID, out tmpInt))
                            {
                                var lastQuery = target.SiteGroup.SiteInfoList.Where(q => q.SiteID == tmpInt);
                                if (lastQuery != null && lastQuery.Count() > 0)
                                {
                                    resEntry.last_site_list.Add(lastQuery.First<SiteInfoGroupDTO>());
                                }
                            }
                        }
                    }
                    else if (resEntry.scan_site.is_margin.HasValue && ((int)resEntry.scan_site.is_margin) == 1)
                    {
                        //如果当前站点是并行流程，无上一站点，变量lastSiteList不为null，但没有子集
                        resEntry.last_site_list = new List<SiteInfoGroupDTO>();
                        resEntry.is_first = true;
                    }
                    else
                    {
                        //以上两种情况都不是的情况，按当前站点的排序（sort）来计算上一站点
                        int tmpSort = resEntry.scan_site.Sort - 1;
                        if (tmpSort <= 0)
                        {
                            //如果计算出来的sort小于0，则当前站点为制程的首站，变量lastSiteList为null
                            resEntry.last_site_list = null;
                            resEntry.is_first = true;
                        }
                        else
                        {
                            //如果计算出来的sort大于0，则按sort取得上一站点
                            var lastQuery = target.SiteGroup.SiteInfoList.Where(q => q.Sort == tmpSort);
                            if (lastQuery != null && lastQuery.Count() > 0)
                            {
                                if (lastQuery.First().SiteID == 8)
                                {
                                    resEntry.last_site_list = new List<SiteInfoGroupDTO>();
                                    resEntry.is_first = true;
                                }
                                else
                                {
                                    resEntry.last_site_list = new List<SiteInfoGroupDTO>();
                                    resEntry.last_site_list.Add(lastQuery.First());
                                    resEntry.is_first = false;
                                }
                            }
                        }
                    }

                    //确定工单上一站的扫码数量
                    if (resEntry.is_first)
                    {
                        //如果是首站，上一站扫码数量为工单的投产数量
                        resEntry.last_qty = target.ProdQty ?? 0;
                    }
                    else
                    {
                        //如果不是首站，查询所有上一站的扫码数量，取较小的为上一站扫码数量
                        resEntry.last_qty = 0;
                        if (resEntry.last_site_list != null && resEntry.last_site_list.Count > 0)
                        {
                            foreach (var item in resEntry.last_site_list)
                            {
                                if (target.scanList != null && target.scanList.Count > 0)
                                {
                                    var tmpQuery = target.scanList.Where(q => q.SiteInfoID == item.SiteID);
                                    tmpDec = tmpQuery != null && tmpQuery.Count() > 0 ? tmpQuery.Sum(q => q.ScanQty) : 0;
                                }
                                else
                                {
                                    tmpDec = 0;
                                }

                                if (tmpDec > 0)
                                {
                                    if (resEntry.last_qty == 0)
                                    {
                                        resEntry.last_qty = tmpDec;
                                    }
                                    else if (resEntry.last_qty != 0 && tmpDec < resEntry.last_qty)
                                    {
                                        resEntry.last_qty = tmpDec;
                                    }
                                }
                            }
                        }
                    }

                    tmpDec = 0;
                    if (target.scanList != null && target.scanList.Count > 0)
                    {
                        var tmpQuery = target.scanList.Where(q => q.SiteInfoID == resEntry.scan_site.SiteID);
                        tmpDec = tmpQuery != null && tmpQuery.Count() > 0 ? tmpQuery.Sum(q => q.ScanQty) : 0;
                    }
                    resEntry.clear_qty = tmpDec;

                    if (scanQty <= 0)
                    {
                        //扫码数量不能为0
                        errStr = $@"扫码数量不能为0";
                        isOK = false;
                        return (isOK, errStr, resEntry);
                    }
                    else if (resEntry.clear_qty + scanQty > (target.ProdQty ?? 0))
                    {
                        errStr = $"当前扫码数量{Math.Round(scanQty, 2)} + 已扫数量{Math.Round(resEntry.clear_qty, 2)} > 工单数量{Math.Round((target.ProdQty ?? 0), 2)}";
                        isOK = false;
                        return (isOK, errStr, resEntry);
                    }
                    else if (resEntry.clear_qty + scanQty > resEntry.last_qty)
                    {
                        errStr = $"当前扫码数量{Math.Round(scanQty, 2)} + 已扫数量{Math.Round(resEntry.clear_qty, 2)} > 上站已扫数量{Math.Round(resEntry.last_qty, 2)}";
                        isOK = false;
                        return (isOK, errStr, resEntry);
                    }
                }
            }
            return (isOK, errStr, resEntry); 
        }
        #endregion







        private async void btnSave_Press(object sender, EventArgs e)
        {
            //查询工单信息
            TargetProdProcessDTO tmpTarget = this._ctrl.SearchTargetForScan(this.txtProdNumber.Text.Trim());

            //查询当前用户信息
            BaseUserDTO tmpUser = Client.Session["User"] as BaseUserDTO;

            //获取服务器当前时间
            DateTime currTime = this._ctrl.GetCurrDateTime();
            string sqlStr = "";


            decimal currQty = decimal.TryParse(this.textBox1.Text.Trim(), out decimal tmpDec) ? tmpDec : 0;
            if (this._curr_site.ID == 6 || this._curr_site.ID == 7 || this._curr_site.ID == 8)
            {
                DataRow[] resultRows1 = PCBSMTDetail.Select("ItemCode = '" + SYGPCB + "'");
                foreach (DataRow row in resultRows1)
                {
                    row["OKNumber"] = OKNumber.Text;
                }
                dynamic OKNumber1 = 0;
                for (int i = 0; i < this.PCBSMTDetail.Rows.Count; i++)
                {
                    if (this.PCBSMTDetail.Rows[i]["OKNumber"].ObjToDecimal() + this.PCBSMTDetail.Rows[i]["YFPNumber"].ObjToDecimal() > this.PCBSMTDetail.Rows[i]["SYGNumber"].ObjToDecimal())
                    {
                        MessageBox.Show("物料" + this.PCBSMTDetail.Rows[i]["ItemCode"].ToString() + "的确认数量超出了可分配数量！");
                        return;
                    }
                    OKNumber1 += this.PCBSMTDetail.Rows[i]["OKNumber"].ObjToDecimal();
                }


                if (OKNumber1 <= 0)
                {
                    MessageBox.Show("确认数量不能为0！");
                    return;
                }

                decimal ThisPCBNumber = 0;
                for (int i = 0; i < this.PCBSMTDetail.Rows.Count; i++)
                {
                    List<SmtPcbConfirm> s1 = Db.Context.Queryable<SmtPcbConfirm>().Where(d => d.prod_number == tmpTarget.ProdNumber && d.mat_number == this.PCBSMTDetail.Rows[i]["ItemCode"].ToString()).ToList();
                    SmtPcbScan SMTPCB = new SmtPcbScan();
                    SMTPCB.confirm_id = s1[0].id;
                    SMTPCB.prod_id = tmpTarget.ID;
                    SMTPCB.prod_number = tmpTarget.ProdNumber;
                    SMTPCB.mat_number = this.PCBSMTDetail.Rows[i]["ItemCode"].ToString();
                    SMTPCB.site_id = this._curr_site.ID;
                    SMTPCB.site_name = this._curr_site.SiteName;
                    SMTPCB.pcb_scan_qty = this.PCBSMTDetail.Rows[i]["OKNumber"].ObjToDecimal();
                    SMTPCB.scan_date = DateTime.Now;
                    SMTPCB.create_user = tmpUser.user_name;
                    SMTPCB.create_date = DateTime.Now;
                    if (this.PCBSMTDetail.Rows[i]["OKNumber"].ObjToDecimal() != 0)
                    {
                        Db.Insertable(SMTPCB).ExecuteCommand();
                    }
                    ThisPCBNumber += this.PCBSMTDetail.Rows[i]["OKNumber"].ObjToDecimal();
                }
                //更新工单的状态和当前所在站点 
                tmpTarget.CurrSiteID = this._curr_site.ID;
                tmpTarget.ProdStatusID = this._curr_site.DefStatus ?? 0;
                //查询当前站点全部物料扫码数量
                decimal sumQty = Db.Context.Queryable<SmtPcbScan>().Where(d => d.site_id == _curr_site.ID && d.prod_number == tmpTarget.ProdNumber).ToList().Sum(d => d.pcb_scan_qty).ObjToDecimal();
                decimal sunConfirmQty = Db.Context.Queryable<SmtPcbConfirm>().Where(d => d.prod_number == tmpTarget.ProdNumber).ToList().Sum(d => d.confirm_qty).ObjToDecimal();
                //如果记录表数量和主表数量一样，就可以过站
                string StatusName = (this._curr_site.ID == 7) ? "生产中" : "等待";
                int statusid = (this._curr_site.ID == 7) ? 4 : 5;
                if (sumQty == sunConfirmQty)
                {
                    //保存工单的扫码记录
                    Db.Ado.ExecuteCommand($@"INSERT INTO pp_scan (pp_id, Prod_Number, Site_ID, Site_Name, Status_ID, Status_name, scan_qty, is_comp, scan_user, Scan_date) 
                        VALUES ('{tmpTarget.ID}', '{tmpTarget.ProdNumber}', '{_curr_site.ID}', '{this._curr_site.SiteName}',
                        '{statusid}', '{StatusName}', '{ThisPCBNumber}', '1', '{tmpUser.user_name}', '{currTime.ToString("yyyy-MM-dd HH:mm:ss")}')");
                    Db.Ado.ExecuteCommand($@"update
	                        target_prod_process
                        set
	                        curr_site_id = {_curr_site.ID}
                        where
	                        prod_number = '{tmpTarget.ProdNumber}' ");

                    if (this._curr_site.ID == 8)
                    {
                        sqlStr = $@"update prod_schedule set is_comp = 1,comp_date = '{currTime.ToString("yyyy-MM-dd HH:mm:ss")}' 
                                    where isnull(is_del,0) = 0 and line_id in (1,13) and prod_number = '{tmpTarget.ProdNumber}'";
                        Db.Ado.ExecuteCommand(sqlStr);
                    }
                }
                else
                {
                    //保存工单的扫码记录
                    Db.Ado.ExecuteCommand($@"INSERT INTO pp_scan (pp_id, Prod_Number, Site_ID, Site_Name, Status_ID, Status_name, scan_qty, is_comp, scan_user, Scan_date) 
                        VALUES ('{tmpTarget.ID}', '{tmpTarget.ProdNumber}', '{_curr_site.ID}', '{_curr_site.SiteName}',
                        '{statusid}', '{StatusName}', '{ThisPCBNumber}', '0', '{tmpUser.user_name}', '{currTime.ToString("yyyy-MM-dd HH:mm:ss")}')");
                }
                this.label2.Text = "";
                this.label4.Text = "";
                this.label6.Text = "";
                this.textBox1.Text = "";
                this.txtProdNumber.Text = "";
                this.SYGNumber.Text = "";
                this.YFPNumber.Text = "";
                this.OKNumber.Text = "";
                this.comboBox1.Text = "请选择PCB型号";
                PCBSMTDetail = new DataTable();
                MessageBox.Show("工单扫码已成功保存！");
                return;
            }
            else
            {
                if (currQty <= 0)
                {
                    MessageBox.Show("本次过站数量必需为大于0的数值！");
                }
                else
                {
                    bool isOK = false;
                    string errStr = "";
                    SiteScanDTO tmpEntry = null;
                    (isOK, errStr, tmpEntry) = this.ChechData(tmpTarget, tmpUser, this._curr_site, this._curr_status, currQty);
                    if (errStr != null && errStr.Length > 0)
                    {
                        MessageBox.Show(errStr);
                    }
                    else
                    {
                        int count = 0;
                        try
                        {
                            if (tmpUser != null && tmpUser.user_name != null && tmpUser.user_name.Trim().Length > 0)
                            {
                                if (currQty + tmpEntry.clear_qty < (tmpTarget.ProdQty ?? 0))
                                {
                                    count = this._ctrl.SaveProdProcessScan(tmpTarget, this._curr_site, this._curr_status, tmpUser, currQty, 0);
                                }
                                else
                                {
                                    count = this._ctrl.SaveProdProcessScan(tmpTarget, this._curr_site, this._curr_status, tmpUser, currQty, 1);
                                }

                                //更新金蝶
                                if (count > 0)
                                {
                                    bool isUpdateKing = false;
                                    if (tmpTarget.ProdNumber.Contains("GL02") || tmpTarget.ProdNumber.Contains("GL03"))
                                    {
                                        if (tmpTarget.SiteGroup.SiteInfoList != null && tmpTarget.SiteGroup.SiteInfoList.Count > 0)
                                        {
                                            var tmpQuery = tmpTarget.SiteGroup.SiteInfoList.Where(q => q.IsLast == 1);
                                            if (tmpQuery != null && tmpQuery.Count() > 0 && tmpQuery.First().SiteID == this._curr_site.ID)
                                            {
                                                isUpdateKing = true;
                                            }
                                        }
                                    }

                                    if (isUpdateKing)
                                    {
                                        string mto = tmpTarget.MtoNumber;
                                        string mo = tmpTarget.MoNumber;
                                        string goods = tmpTarget.GoodsNumber;
                                        KingdeeControler tmpCtrl = new KingdeeControler();
                                        bool openLock = await tmpCtrl.UpdateMoentryMesStatus(mo, goods, 1);
                                    }
                                }
                                MessageBox.Show("工单扫码已成功保存！");
                            }
                            else
                            {
                                MessageBox.Show("用户尚未登陆，保存失败！");
                            }
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("工单扫码记录保存失败！" + "\r\n" + ex.Message);
                        }
                        finally
                        {
                            this.label2.Text = "";
                            this.label4.Text = "";
                            this.label6.Text = "";
                            this.textBox1.Text = "";
                            this.txtProdNumber.Text = "";
                            SYGNumber.Text = "";
                            YFPNumber.Text = "";
                            OKNumber.Text = "";
                            this.comboBox1.Text = "请选择PCB型号";
                        }
                    }
                }
            }

        }

        private void btnClose_Press(object sender, EventArgs e)
        {
            this.Close();
        }

        private void button1_Press(object sender, EventArgs e)
        {
            this.popItemCode.ShowDialog();
        }

        private void popItemCode_Selected(object sender, EventArgs e)
        {
            ////第一次不进去
            //if (this.button1.Text != "请选择PCB型号  >")
            //{
            //    DataRow[] resultRows1 = PCBSMTDetail.Select("ItemCode = '" + this.button1.Text + "'");
            //    foreach (DataRow row in resultRows1)
            //    {
            //        row["OKNumber"] = OKNumber.Text;
            //    }
            //}




        }

        private void OKNumber_TextChanged(object sender, EventArgs e)
        {

        }

        private void comboBox1_ItemSelected(object sender, EventArgs e)
        {
            //第一次不进去
            if (SYGPCB != "")
            {
                DataRow[] resultRows1 = PCBSMTDetail.Select("ItemCode = '" + SYGPCB + "'");
                foreach (DataRow row in resultRows1)
                {
                    row["OKNumber"] = OKNumber.Text;
                }
            }

            SYGPCB = this.comboBox1.Text;
            var query = from row in PCBSMTDetail.AsEnumerable()
                        where row.Field<string>("ItemCode") == this.comboBox1.Text
                        select row;
            if (query != null)
            {
                DataRow[] resultRows = query.ToArray();
                SYGNumber.Text = resultRows[0].ItemArray[1].ToString();
                YFPNumber.Text = resultRows[0].ItemArray[2].ToString();
                OKNumber.Text = resultRows[0].ItemArray[3].ToString();
            }
        }
    }
}